#include <iostream>
#include <cuda_runtime.h>
#include "cublas_v2.h"
#include "../common/common.h"
#define DEVICENUM 0
#define M 5 // 5行
#define N 6 // 6列

int main(int argc, char **argv)
{
    cudaSetDevice(DEVICENUM);

    // 声明主机端矩阵A，主机端向量X，主机端向量Y，并申请内存
    float *A = (float *)malloc(sizeof(float) * M * N);
    float *X = (float *)malloc(sizeof(float) * M);
    float *Y = (float *)malloc(sizeof(float) * N);

    initialDataIncreasing(A, M * N);
    initialDataConstValue(X, M, 1);
    initialDataConstValue(Y, N, 2);

    printMatrix(A, M, N, "A");
    // printVector(X, M, "X");
    // printVector(Y, N, "M");

    // 声明设备端矩阵dA，设备端向量dX，设备端向量dY,并出申请内存
    float *dA, *dX, *dY;
    CHECK(cudaMalloc((void **)&dA, sizeof(float) * M * N));
    CHECK(cudaMalloc((void **)&dX, sizeof(float) * M));
    CHECK(cudaMalloc((void **)&dY, sizeof(float) * N));

    // cublasHandle_t handle = 0; // 创建句柄，这里指演示了向量数据的传递，并没有用到，所以可注释掉
    // CHECK_CUBLAS(cublasCreate(&handle));

    // 以前需要使用cudaMemcpy函数上传数据到gpu，如果直接调用cublas库，其函数会自动做这些事
    // 1. 向量X到向量dX的复制
    CHECK_CUBLAS(cublasSetVector(M, sizeof(float), X, 1, dX, 1));

    // 2. 矩阵A中的一行到向量dY的复制
    CHECK_CUBLAS(cublasSetVector(N, sizeof(float), A, 1, dY, 1));
    CHECK_CUBLAS(cublasGetVector(N, sizeof(float), dY, 1, Y, 1)); // gpu-->cpu,即向量dY-->Y
    printVector(Y, N, "select one row res");

    // 3. 矩阵A中的一列到向量dX的复制
    CHECK_CUBLAS(cublasSetVector(M, sizeof(float), A, N, dX, 1)); // 注意，这里 间隔incx=N=列数
    CHECK_CUBLAS(cublasGetVector(M, sizeof(float), dX, 1, X, 1)); // gpu-->cpu,即向量dX-->X
    printVector(X, M, "select one col res");

    free(A);
    free(X);
    free(Y);
    cudaFree(dA);
    cudaFree(dX);
    cudaFree(dY);

    return 0;
}